HAL I2C initialization and configuration functions migration

The goal of this page is to show how to migrate the initialization sequence using STM32CubeMX2:

  • Open STM32CubeMX2 I2C configuration panel.

  • Configure the SW layer HAL.

  • Configure the I2C main features.

  • Configure the additional I2C features if needed.

  • Configure the I2C GPIO pins.

  • Configure the I2C DMA(s) if the application requires to use the I2C in DMA mode.

  • Configure the NVIC if the application requires the I2C to be used in IT mode.

  • Generate the code.

Note

The configuration below might varies from a series to another.

HAL I2C configuration panel

Create a new project with the STM32CubeMX2, then start the initialization and the main configuration.

Project configuration panel

HAL I2C main features configuration

Configure the I2C main features.

I2C main feature configuration

HAL I2C advanced features configuration

Configure the advanced I2C features.

I2C advanced feature configuration

GPIO configuration

Configure GPIO pins.

I2C GPIO configuration

DMA configuration

Configure the DMA for data reception as needed.

I2C DMA TX and RX configuration

NVIC configuration

Configure the NVIC in case of an interrupt.

I2C NVIC configuration

Generated I2C initialization and de-initialization sequences

The I2C initialization sequence is generated in the mx_i2c1_hal_init function in mx_i2c1.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

Related concepts:

STM32CubeMX2 Generated : I2C initialization and de-initialization sequences

Topic

Code Snippet HAL1

Code Snippet HAL2

Handle declaration

I2C_HandleTypeDef hi2c1;
DMA_HandleTypeDef handle_GPDMA1_Channel0;
DMA_HandleTypeDef handle_GPDMA1_Channel1;
static hal_i2c_handle_t hI2C1;
static hal_dma_handle_t hGPDMA1_CH0;
static hal_dma_handle_t hGPDMA1_CH1;

Initialization and configuration sequence

static void MX_I2C1_Init(void)
{


  I2C_AutonomousModeConfTypeDef sConfigI2C1 = {0};

  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x30909DEC;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_ENABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  {
    Error_Handler();
  }

  sConfigI2C1.TriggerState = I2C_AUTO_MODE_ENABLE;
  sConfigI2C1.TriggerSelection = I2C_GRP1_GPDMA_CH0_TCF_TRG;
  sConfigI2C1.TriggerPolarity = I2C_TRIG_POLARITY_RISING;
  if (HAL_I2CEx_SetConfigAutonomousMode(&hi2c1, &sConfigI2C1) != HAL_OK)
  {
    Error_Handler();
  }

}
static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOB_CLK_ENABLE();

}
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hi2c->Instance==I2C1)
  {

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
    PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    __HAL_RCC_I2C1_CLK_ENABLE();

    handle_GPDMA1_Channel1.Instance = GPDMA1_Channel1;
    handle_GPDMA1_Channel1.Init.Request = GPDMA1_REQUEST_I2C1_RX;
    handle_GPDMA1_Channel1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
    handle_GPDMA1_Channel1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    handle_GPDMA1_Channel1.Init.SrcInc = DMA_SINC_FIXED;
    handle_GPDMA1_Channel1.Init.DestInc = DMA_DINC_FIXED;
    handle_GPDMA1_Channel1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
    handle_GPDMA1_Channel1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
    handle_GPDMA1_Channel1.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
    handle_GPDMA1_Channel1.Init.SrcBurstLength = 1;
    handle_GPDMA1_Channel1.Init.DestBurstLength = 1;
    handle_GPDMA1_Channel1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
    handle_GPDMA1_Channel1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    handle_GPDMA1_Channel1.Init.Mode = DMA_NORMAL;
    if (HAL_DMA_Init(&handle_GPDMA1_Channel1) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hi2c, hdmarx, handle_GPDMA1_Channel1);

    if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel1, DMA_CHANNEL_NPRIV) != HAL_OK)
    {
      Error_Handler();
    }

    handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
    handle_GPDMA1_Channel0.Init.Request = GPDMA1_REQUEST_I2C1_TX;
    handle_GPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
    handle_GPDMA1_Channel0.Init.Direction = DMA_MEMORY_TO_PERIPH;
    handle_GPDMA1_Channel0.Init.SrcInc = DMA_SINC_FIXED;
    handle_GPDMA1_Channel0.Init.DestInc = DMA_DINC_FIXED;
    handle_GPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
    handle_GPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
    handle_GPDMA1_Channel0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
    handle_GPDMA1_Channel0.Init.SrcBurstLength = 1;
    handle_GPDMA1_Channel0.Init.DestBurstLength = 1;
    handle_GPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
    handle_GPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    handle_GPDMA1_Channel0.Init.Mode = DMA_NORMAL;
    if (HAL_DMA_Init(&handle_GPDMA1_Channel0) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hi2c, hdmatx, handle_GPDMA1_Channel0);

    if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
    {
      Error_Handler();
    }

    HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
    HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
  }

}
hal_i2c_handle_t *mx_i2c1_hal_init(void)
{
    hal_i2c_config_t i2c_config;

    if (HAL_I2C_Init(&hI2C1, HAL_I2C1) != HAL_OK)
    {
        return NULL;
    }

    HAL_RCC_I2C1_EnableClock();

    i2c_config.timing = 0x30813537;
    i2c_config.addressing_mode = HAL_I2C_ADDRESSING_7BIT;
    i2c_config.own_address1 = 0 << 1U;
    if (HAL_I2C_SetConfig(&hI2C1, &i2c_config) != HAL_OK)
    {
        return NULL;
    }

    HAL_I2C_EnableAnalogFilter(&hI2C1);

    HAL_I2C_SLAVE_DisableClockStretching(&hI2C1);

    HAL_RCC_GPIOA_EnableClock();

    HAL_RCC_GPIOB_EnableClock();

    hal_gpio_config_t  gpio_config;

    gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
    gpio_config.output_type = HAL_GPIO_OUTPUT_OPENDRAIN;
    gpio_config.pull        = HAL_GPIO_PULL_NO;
    gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
    gpio_config.alternate   = HAL_GPIO_AF_9;
    HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_8, &gpio_config);


    gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
    gpio_config.output_type = HAL_GPIO_OUTPUT_OPENDRAIN;
    gpio_config.pull        = HAL_GPIO_PULL_NO;
    gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
    gpio_config.alternate   = HAL_GPIO_AF_4;
    HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_7, &gpio_config);

    /* Configure the DMA TX */
    HAL_RCC_LPDMA1_EnableClock();

    if (HAL_DMA_Init(&hLPDMA1_CH0, HAL_LPDMA1_CH0) != HAL_OK)
    {
      return NULL;
    }

   hal_dma_direct_xfer_config_t xfer_cfg_i2c1_tx_dma;
    xfer_cfg_i2c1_tx_dma.request         = HAL_LPDMA1_REQUEST_I2C1_TX;
    xfer_cfg_i2c1_tx_dma.direction       = HAL_DMA_DIRECTION_MEMORY_TO_PERIPH;
    xfer_cfg_i2c1_tx_dma.src_inc         = HAL_DMA_SRC_ADDR_FIXED;
    xfer_cfg_i2c1_tx_dma.dest_inc        = HAL_DMA_DEST_ADDR_FIXED;
    xfer_cfg_i2c1_tx_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_BYTE;
    xfer_cfg_i2c1_tx_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_BYTE;
    xfer_cfg_i2c1_tx_dma.priority        = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;

    if (HAL_DMA_SetConfigPeriphDirectXfer(&hLPDMA1_CH0, &xfer_cfg_i2c1_tx_dma) != HAL_OK)
    {
      return NULL;
    }

    /* Enable the interruption for LPDMA1_CH0 */
    HAL_CORTEX_NVIC_SetPriority(LPDMA1_CH0_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
    HAL_CORTEX_NVIC_EnableIRQ(LPDMA1_CH0_IRQn);

    /* Link the Transmit DMA handle to the I2C handle */
    if (HAL_I2C_SetTxDMA(&hI2C1, &hLPDMA1_CH0) != HAL_OK)
    {
      return NULL;
    }

    /* Configure the DMA RX */
    HAL_RCC_LPDMA1_EnableClock();

    if (HAL_DMA_Init(&hLPDMA1_CH1, HAL_LPDMA1_CH1) != HAL_OK)
    {
      return NULL;
    }

   hal_dma_direct_xfer_config_t xfer_cfg_i2c1_rx_dma;
    xfer_cfg_i2c1_rx_dma.request         = HAL_LPDMA1_REQUEST_I2C1_RX;
    xfer_cfg_i2c1_rx_dma.direction       = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
    xfer_cfg_i2c1_rx_dma.src_inc         = HAL_DMA_SRC_ADDR_FIXED;
    xfer_cfg_i2c1_rx_dma.dest_inc        = HAL_DMA_DEST_ADDR_FIXED;
    xfer_cfg_i2c1_rx_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_BYTE;
    xfer_cfg_i2c1_rx_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_BYTE;
    xfer_cfg_i2c1_rx_dma.priority        = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;

    if (HAL_DMA_SetConfigPeriphDirectXfer(&hLPDMA1_CH1, &xfer_cfg_i2c1_rx_dma) != HAL_OK)
    {
      return NULL;
    }

    /* Enable the interruption for LPDMA1_CH1 */
    HAL_CORTEX_NVIC_SetPriority(LPDMA1_CH1_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
    HAL_CORTEX_NVIC_EnableIRQ(LPDMA1_CH1_IRQn);

    /* Link the Receive DMA handle to the I2C handle */
    if (HAL_I2C_SetRxDMA(&hI2C1, &hLPDMA1_CH1) != HAL_OK)
    {
      return NULL;
    }

    if (HAL_RCC_I2C1_SetKernelClkSource(HAL_RCC_I2C1_CLK_SRC_PCLK1) != HAL_OK)
    {
      return NULL;
    }

    HAL_CORTEX_NVIC_SetPriority(I2C1_EV_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
    HAL_CORTEX_NVIC_EnableIRQ(I2C1_EV_IRQn);

    HAL_CORTEX_NVIC_SetPriority(I2C1_ERR_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
    HAL_CORTEX_NVIC_EnableIRQ(I2C1_ERR_IRQn);

    return &hI2C1;
}

Deinitialization sequence

void MX_I2C_DeInit(void)
{
  if (HAL_I2C_DeInit(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
  if(hi2c->Instance==I2C1)
  {

    __HAL_RCC_I2C1_CLK_DISABLE();
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10);

    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_11);

    HAL_DMA_DeInit(hi2c->hdmarx);
    HAL_DMA_DeInit(hi2c->hdmatx);

    HAL_NVIC_DisableIRQ(I2C1_EV_IRQn);
    HAL_NVIC_DisableIRQ(I2C1_ER_IRQn);

  }

}
void mx_i2c1_hal_deinit(void)
{
  HAL_CORTEX_NVIC_DisableIRQ(I2C1_EV_IRQn);

  HAL_CORTEX_NVIC_DisableIRQ(I2C1_ERR_IRQn);

  (void)HAL_I2C_DeInit(&hI2C1);

  HAL_RCC_I2C1_Reset();

  HAL_RCC_I2C1_DisableClock();

  HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_8);

  HAL_GPIO_DeInit(HAL_GPIOB, HAL_GPIO_PIN_7);

  /* De-initialize the DMA channel */
  HAL_DMA_DeInit(&hLPDMA1_CH0);

  /* Disable the interruption for DMA */
  HAL_CORTEX_NVIC_DisableIRQ(LPDMA1_CH0_IRQn);

  /* De-initialize the DMA channel */
  HAL_DMA_DeInit(&hLPDMA1_CH1);

  /* Disable the interruption for DMA */
  HAL_CORTEX_NVIC_DisableIRQ(LPDMA1_CH1_IRQn);

}

IRQ handle function

void GPDMA1_Channel0_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&handle_GPDMA1_Channel0);
}
void GPDMA1_Channel1_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&handle_GPDMA1_Channel1);
}
void I2C1_EV_IRQHandler(void)
{
  HAL_I2C_EV_IRQHandler(&hi2c1);
}
void I2C1_ER_IRQHandler(void)
{
  HAL_I2C_ER_IRQHandler(&hi2c1);
}
void LPDMA1_CH0_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hLPDMA1_CH0);
}
void LPDMA1_CH1_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hLPDMA1_CH1);
}
void I2C1_EV_IRQHandler(void)
{
    HAL_I2C_EV_IRQHandler(&hI2C1);
}
void I2C1_ERR_IRQHandler(void)
{
    HAL_I2C_ERR_IRQHandler(&hI2C1);
}